package com.zqj.project.service;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zqj.project.common.exception.BizException;
import com.zqj.project.converter.OrderConverter;
import com.zqj.project.converter.OrderDetailConverter;
import com.zqj.project.entity.OrderPO;
import com.zqj.project.entity.PhonePO;
import com.zqj.project.factory.OrderFactory;
import com.zqj.project.model.Order;
import com.zqj.project.model.OrderDetail;
import com.zqj.project.repository.OrderDetailMapper;
import com.zqj.project.repository.OrderMapper;
import com.zqj.project.repository.PhoneMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @Description: OrderServiceImpl
 * @Author: 22001010704 Zhang Qijian
 * @CreateTime: 2024/11/8 15:39
 * @Version: 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final OrderMapper orderMapper;
    private final OrderDetailMapper orderDetailMapper;
    private final PhoneMapper phoneMapper;

    @Override
    public IPage<Order> page(Order order, IPage<Order> page) {
        final Long count = this.orderMapper.selectCount(OrderFactory.lbqWrapper(order));
        if (Objects.equals(0L, count)) {
            return page;
        }
        page.setTotal(count);
        return page.setRecords(OrderConverter.toOrderModelList(this.orderMapper.selectPage(new Page<>(page.getCurrent(), page.getSize(), page.getTotal()), OrderFactory.lbqWrapper(order)).getRecords()));
    }

    @Override
    public Order info(Long id) {
        OrderPO orderPo = this.orderMapper.selectById(id);
        if (Objects.isNull(orderPo)) {
            throw new BizException("订单不存在");
        }
        return OrderConverter.toOrderModel(orderPo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized Boolean pageOrder(Order order) {
        // 生成订单id
        Long orderId = IdUtil.getSnowflake().nextId();
        order.setId(orderId);
        // 通过参数得到手机id
        Long productId = order.getProductId();
        // 查到手机对象
        PhonePO phonePo = this.phoneMapper.selectById(productId);
        if (Objects.isNull(phonePo)) {
            throw new BizException("商品不存在");
        }
        // 总价 = 单价 × 数量
        BigDecimal totalPrice = phonePo.getPrice().multiply(BigDecimal.valueOf(order.getNumber()));
        // 订单总价
        order.setTotalPrice(totalPrice);
        // 设置订单状态为0-待付款
        order.setStatus(0);
        // 构造单个订单明细
        OrderDetail orderDetail = new OrderDetail(null, orderId, productId, phonePo.getName(), order.getNumber(), phonePo.getPrice(), totalPrice, null, null);
        // 创建订单明细
        this.orderDetailMapper.insert(OrderDetailConverter.toOrderDetailPo(orderDetail));
        // 创建订单
        this.orderMapper.insert(OrderConverter.toOrderPo(order));
        // 计算扣减的库存
        phonePo.setCount(phonePo.getCount() - order.getNumber());
        // 更新商品库存
        return this.phoneMapper.updateById(phonePo) == 1;
    }

    @Override
    public Boolean pay(Order order) {
        OrderPO orderPo = this.orderMapper.selectById(order.getId());
        if (Objects.isNull(orderPo)) {
            throw new BizException("订单不存在");
        }
        switch (orderPo.getStatus()) {
            case -1:
                throw new BizException("订单已取消, 无法付款");
            case 0:
                break;
            case 1:
                throw new BizException("订单已支付");
            case 2:
                throw new BizException("订单已发货, 无法付款");
            case 3:
                throw new BizException("订单已完成, 无法付款");
            default:
                throw new BizException("订单状态异常");
        }
        order.setStatus(1);
        return this.orderMapper.updateById(OrderConverter.toOrderPo(order)) == 1;
    }

    @Override
    public Boolean dispatch(Order order) {
        OrderPO orderPo = this.orderMapper.selectById(order.getId());
        if (Objects.isNull(orderPo)) {
            throw new BizException("订单不存在");
        }
        switch (orderPo.getStatus()) {
            case -1:
                throw new BizException("订单已取消, 无法发货");
            case 0:
                throw new BizException("订单未付款, 无法发货");
            case 1:
                break;
            case 2:
                throw new BizException("订单已发货");
            case 3:
                throw new BizException("订单已完成, 无法发货");
            default:
                throw new BizException("订单状态异常");
        }
        order.setStatus(2);
        return this.orderMapper.updateById(OrderConverter.toOrderPo(order)) == 1;
    }

    @Override
    public Boolean complete(Order order) {
        OrderPO orderPo = this.orderMapper.selectById(order.getId());
        if (Objects.isNull(orderPo)) {
            throw new BizException("订单不存在");
        }
        switch (orderPo.getStatus()) {
            case -1:
                throw new BizException("订单已取消, 无法确认收货");
            case 0:
                throw new BizException("订单未付款, 无法确认收货");
            case 1:
                throw new BizException("订单未发货, 无法确认收货");
            case 2:
                break;
            case 3:
                throw new BizException("订单已完成");
            default:
                throw new BizException("订单状态异常");
        }
        order.setStatus(3);
        return this.orderMapper.updateById(OrderConverter.toOrderPo(order)) == 1;
    }

    @Override
    public Boolean cancel(Order order) {
        OrderPO orderPo = this.orderMapper.selectById(order.getId());
        if (Objects.isNull(orderPo)) {
            throw new BizException("订单不存在");
        }
        switch (orderPo.getStatus()) {
            case -1:
                throw new BizException("订单已取消, 无法再次取消");
            case 0, 1:
                break;
            case 2:
                throw new BizException("订单已发货, 无法取消");
            case 3:
                throw new BizException("订单已完成, 无法取消");
            default:
                throw new BizException("订单状态异常");
        }
        order.setStatus(-1);
        return this.orderMapper.updateById(OrderConverter.toOrderPo(order)) == 1;
    }

    @Override
    public Boolean edit(Order order) {
        OrderPO orderPo = this.orderMapper.selectById(order.getId());
        if (Objects.isNull(orderPo)) {
            throw new BizException("订单不存在");
        }
        switch (orderPo.getStatus()) {
            case -1:
                throw new BizException("订单已取消, 无法编辑");
            case 0, 1:
                break;
            case 2:
                throw new BizException("订单已发货, 无法编辑");
            case 3:
                throw new BizException("订单已完成, 无法编辑");
            default:
                throw new BizException("订单状态异常");
        }
        return this.orderMapper.updateById(OrderConverter.toOrderPo(order)) == 1;
    }

    @Override
    public Boolean delete(Long id) {
        return this.orderMapper.deleteById(id) == 1;
    }

}